/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import React, { useEffect, useCallback, useState } from "react";
import {
  Popconfirm,
  Button,
  Row,
  Col,
  Form,
  Input,
  List,
  Drawer,
  Descriptions,
  Upload,
  Icon,
  Alert,
} from "antd";
import { connect } from "dva";
import { debounce } from "lodash";
import "braft-editor/dist/index.css";
import "braft-editor/dist/output.css";
import BraftEditor from "braft-editor";
import { ContentUtils } from "braft-utils";
import styles from "../style.less";

const FormItem = Form.Item;
const ListItem = List.Item;
const formItemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 4 },
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 20 },
  },
};

const excludeControls = ["code", "emoji", "media"];

const switchStatus = status => {
  switch (status) {
    case "1":
      return "未完成";
    case "2":
      return "待审核";
    case "3":
      return "已审核发布";
    case "4":
      return "审核未通过";
    default:
      return "-";
  }
};

const AddModal = Form.create()(({ visible, toggleModal, form, dispatch, record = {}, page }) => {
  const { getFieldDecorator, validateFields, resetFields, setFieldsValue } = form;
  const { status, id, content: contentText, title: contentTitle, sub_title } = record;
  const [title, setTitle] = useState("");
  const [editable, setEditable] = useState(true);
  const [content, setContent] = useState(BraftEditor.createEditorState(contentText));

  useEffect(
    () => {
      editable &&
        setFieldsValue({
          content: BraftEditor.createEditorState(contentText),
        });
    },
    [editable, setFieldsValue, contentText]
  );

  useEffect(
    () => {
      switch (status) {
        case "newAdd":
          setTitle("新建通知");
          setEditable(true);
          break;
        case "2":
          setEditable(false);
          setTitle("通知详情");
          break;
        case "1":
          setEditable(true);
          setTitle("编辑通知");
          break;
        default:
          setEditable(false);
          setTitle("通知详情");
          break;
      }
    },
    [status]
  );

  const handleModal = useCallback(
    open => {
      toggleModal(open);
      resetFields();
    },
    [toggleModal, resetFields]
  );

  const onOk = useCallback(
    isDraft => {
      validateFields((err, fieldsValue) => {
        if (err) return;
        const url = status == "newAdd" ? "setup/saveNotice" : "setup/editNotice";
        dispatch({
          type: url,
          payload: {
            title: fieldsValue.title,
            sub_title: fieldsValue.sub_title,
            content: fieldsValue.content.toHTML(),
            id,
            status: isDraft ? "1" : "2",
          },
        }).then(() => {
          dispatch({
            type: "setup/getNoticeList",
            payload: {
              page: status == "newAdd" ? 1 : page,
              pageSize: 30,
            },
          });
          handleModal(false);
        });
      });
    },
    [handleModal, validateFields, dispatch, status, id, page]
  );

  const onDelet = useCallback(
    () => {
      dispatch({
        type: "setup/delNoticeList",
        payload: {
          id,
        },
      }).then(() => {
        handleModal(false);
        dispatch({
          type: "setup/getNoticeList",
          payload: {
            page,
            pageSize: 30,
          },
        });
      });
    },
    [page, id, dispatch, handleModal]
  );

  const onCancel = useCallback(
    () => {
      handleModal(false);
    },
    [handleModal]
  );

  const handleChange = debounce(
    editorState => {
      setFieldsValue({
        content: editorState,
      });
      setContent(editorState);
    },
    300,
    {
      leading: true,
      trailing: false,
    }
  );

  const braftUploadFn = param => {
    if (!param.file) {
      return false;
    }
    const formData = new FormData();
    formData.append("img", param.file);
    dispatch({
      type: "setup/getImgURL",
      payload: formData,
    }).then(url => {
      if (url) {
        setFieldsValue({
          content: ContentUtils.insertMedias(content, [
            {
              type: "IMAGE",
              url,
              width: "100%",
            },
          ]),
        });
      }
    });
  };

  const extendControls = [
    {
      key: "antd-uploader",
      type: "component",
      component: (
        <Upload accept="image/*" showUploadList={false} customRequest={braftUploadFn}>
          {/* 这里的按钮最好加上type="button"，以避免在表单容器中触发表单提交，用Antd的Button组件则无需如此 */}
          <button type="button" className="control-item button upload-button" data-title="插入图片">
            <Icon type="picture" theme="filled" />
          </button>
        </Upload>
      ),
    },
  ];

  const hooks = {
    "toggle-link": ({ href, target }) => {
      href = href.indexOf("http") === 0 ? href : `http://${href}`;
      return { href, target };
    },
    "set-image-link": href => {
      href = href.indexOf("http") === 0 ? href : `http://${href}`;
      return href;
    },
  };

  return (
    <Drawer
      destroyOnClose
      bodyStyle={{ paddingBottom: 80 }}
      width="50%"
      placement="right"
      closable={false}
      visible={visible}
      title={title}
      onClose={onCancel}
    >
      {editable ? (
        <Form {...formItemLayout}>
          <FormItem label="通知标题">
            {getFieldDecorator("title", {
              initialValue: contentTitle,
              rules: [{ required: true, message: "请输入标题内容!" }],
            })(<Input placeholder="请输入通知标题" />)}
          </FormItem>
          <FormItem label="副标题">
            {getFieldDecorator("sub_title", {
              initialValue: sub_title,
              rules: [{ required: true, message: "请输入副标题内容!" }],
            })(<Input placeholder="请输入副标题" />)}
          </FormItem>
          <FormItem label="内容">
            {getFieldDecorator("content", {
              initialValue: BraftEditor.createEditorState(contentText),
              rules: [{ required: true, message: "请输入通知内容!" }],
            })(
              <BraftEditor
                hooks={hooks}
                onChange={handleChange}
                className={styles.braftEditor}
                excludeControls={excludeControls}
                extendControls={extendControls}
                placeholder="请输入通知内容"
              />
            )}
          </FormItem>
        </Form>
      ) : (
        <Descriptions title={contentTitle}>
          <Descriptions.Item>
            <h3>{sub_title}</h3>
            <div dangerouslySetInnerHTML={{ __html: contentText }} />
          </Descriptions.Item>
        </Descriptions>
      )}
      <div
        style={{
          position: "absolute",
          right: 0,
          bottom: 0,
          width: "100%",
          borderTop: "1px solid #e9e9e9",
          padding: "10px 16px",
          background: "#fff",
          textAlign: "right",
          zIndex: 10,
        }}
      >
        {editable ? (
          <>
            <Button type="ghost" onClick={() => onOk(true)} style={{ marginRight: 8 }}>
              保存草稿
            </Button>
            <Button onClick={() => onOk(false)} type="primary">
              提交审核
            </Button>
          </>
        ) : (
          <Popconfirm
            okText="确认"
            cancelText="取消"
            title="删除后将无法查看该通知，确定删除吗？"
            onConfirm={onDelet}
            placement="topRight"
          >
            <Button type="danger" style={{ marginRight: 8 }}>
              删除
            </Button>
          </Popconfirm>
        )}
      </div>
    </Drawer>
  );
});

const NotificationManagement = ({ noticeList, dispatch, loading }) => {
  const [visible, setVisible] = useState(false);
  const [page, setPage] = useState(1);
  const [record, setRecord] = useState({});

  const toggleModal = useCallback(open => {
    setVisible(open);
  }, []);

  useEffect(
    () => {
      dispatch({
        type: "setup/getNoticeList",
        payload: {
          page,
          pageSize: 30,
        },
      });
    },
    [dispatch, page]
  );

  const handleDelet = useCallback(
    id => {
      dispatch({
        type: "setup/delNoticeList",
        payload: {
          id,
        },
      }).then(() => {
        dispatch({
          type: "setup/getNoticeList",
          payload: {
            page,
            pageSize: 30,
          },
        });
      });
    },
    [dispatch, page]
  );

  const onEdit = useCallback(
    itemRecord => {
      setRecord(itemRecord);
      toggleModal(true);
    },
    [toggleModal]
  );

  const onPageChange = useCallback(currentPae => {
    setPage(currentPae);
  }, []);

  return (
    <div>
      <Row type="flex" align="middle" style={{ marginBottom: 16 }} gutter={[16]}>
        <Col style={{ flex: 1 }}>
          <Alert
            type="warning"
            message="新建通知，客服审核通过后，下属驿站会收到app推送，可在驿站快报中看到。每周只能发送5次通知。"
            showIcon
          />
        </Col>
        <Col>
          <Button type="primary" onClick={() => onEdit({ status: "newAdd" })}>
            新建通知
          </Button>
        </Col>
      </Row>
      <List
        loading={loading}
        dataSource={noticeList.list}
        pagination={{
          onChange: onPageChange,
          pageSize: 30,
          total: noticeList.total,
          current: noticeList.page,
        }}
        renderItem={item => {
          const notFinish = item.status === "1";
          const finished = item.status === "3";
          return (
            <ListItem
              actions={[
                <a key="edit" onClick={() => onEdit(item)}>
                  {notFinish ? "编辑" : "详情"}
                </a>,
                <Popconfirm
                  title="删除后将无法查看该通知，确定删除吗？"
                  okText="确认"
                  cancelText="取消"
                  placement="topRight"
                  onConfirm={() => handleDelet(item.id)}
                >
                  <a key="del">删除</a>
                </Popconfirm>,
              ]}
            >
              <Row type="flex" style={{ flex: 1 }} gutter={[20]} align="middle">
                <Col span={8}>{item.title}</Col>
                <Col span={8} style={{ color: finished ? "#B7B7B7" : "" }}>
                  {switchStatus(item.status)}
                </Col>
                <Col span={8}>{item.created_time}</Col>
              </Row>
            </ListItem>
          );
        }}
      />
      <AddModal
        visible={visible}
        toggleModal={toggleModal}
        dispatch={dispatch}
        record={record}
        page={page}
      />
    </div>
  );
};

export default connect(({ loading, setup }) => ({
  noticeList: setup.noticeList,
  firstPageList: setup.firstPageList,
  loading: loading.effects["setup/getNoticeList"],
}))(React.memo(NotificationManagement));
